#include "Semaforo.h"


/* Funcion que crea un semaforo con el identificador ID y lo inicializa con 
 * el valor s0 (0 = rojo, 1=verde)  */
int semInit(int ID, int s0) {
  int S;
  union semun {
    int val;
    struct semid_ds *buf;
    unsigned short int *array;
    struct seminfo *__buf;
  } arg;

  S = semget(ID, 1, (IPC_CREAT | 0666));
  arg.val = s0;
  semctl(S, 0, SETVAL, arg);

  return S;  
} // sem_sys5


/* Funcion que comprueba el valor de un semaforo  */
int semAt(int ID) {
  int S;
  S = semget(ID, 1, 0666);
  return S;
} // sem_sys5


/* Funcion que elimina un semaforo */
void semFree(int S) {

  /* union semun {
    int val;
    struct semid_ds *buf;
    unsigned short int *array;
    struct seminfo *__buf;
  } arg; */

  semctl(S, 0, IPC_RMID, NULL);
} // ~sem_sys5


/* Funcion que intenta coger un semaforo. Si el semaforo ya esta ocupado,
 * el proceso duerme hasta que se libera  */
int semWait(int S) {
  // Devuelve 1 si correcto. 0 en caso contrario
  //printf("pid %d hace semWait\n", getpid());
  struct sembuf WAIT;
 
  WAIT.sem_num = 0;
  WAIT.sem_op = -1;
  WAIT.sem_flg = 0;

  //return (semop(S, &WAIT, 1) != -1); //espera interrumpible
  
   //MODIFICACION:
   /* int r = 0;
   while (r == -1) { //espera ininterrumpible
     r = semop(S, &WAIT, 1);
     //printf("sale una vez. r = %d \n", r);
   }

   return r;*/

   while (semop(S, &WAIT, 1) == -1);
   return 1;
} // Wait


/* Funcion que libera un semaforo */
int semSignal(int S) {
  // Devuelve 1 si correcto. 0 en caso contrario
  //printf("pid %d hace semSignal\n", getpid());

  struct sembuf SIGNAL;

  SIGNAL.sem_num = 0;
  SIGNAL.sem_op = 1;
  SIGNAL.sem_flg = 0;

  return (semop(S, &SIGNAL, 1) != -1);
} // Signal

